#ifndef TS_SERVICE_C
#define TS_SERVICE_C
/*********************************************************************************************************************/
#include "ca51f_config.h"
#include "includes\ca51f3sfr.h"
#include "includes\ca51f3xsfr.h"
#include "includes\gpiodef_f3.h"
#include "Library\includes\uart.h"
/*********************************************************************************************************************/
#include "TS_Lib\Includes\ts_def.h"
#include "TS_Lib\Includes\ts_api.h"
#include "TS_Lib\Includes\ts_service.h"		  
/*********************************************************************************************************************/
code unsigned char *pXSFR[]=
{
	&P10F,
	&P11F,
	&P12F,
	&P13F,
	&P14F,
	&P15F,
	&P16F,
	&P17F,
	&P37F,
	&P36F,
	&P35F,
	&P34F,
	&P07F,
	&P06F,
	&P05F,
	&P04F,
	&P03F,
	&P02F,
	&P01F,
	&P00F,
};
void TS_IO_init(void)
{
	unsigned char i;
	unsigned char *pPinS;
	GPIO_Init(P21F,P21_CAP_SETTING);
	for(i = 0; i < TS_Cnt; i++)
	{
		pPinS = pXSFR[TS_CH[i]];
		*pPinS = 4;
	}
}
void TS_ScanStart(void)
{	
	unsigned char i,j;	
	for(i = 0; i < 6; i++)					
	{
		if(TS_Index + i >= TS_Cnt)
		{
			INDEX = i;
			TKCHS = MPOL(0) | NPOL(1) | TKCHS(21);
			for(j = i+1; j < 6; j++)
			{
				INDEX = j;
				TKCHS = MPOL(0) | NPOL(1) | TKCHS(0);	
			}
			break;
		}
		INDEX = i;
		TKCHS = MPOL(0) | NPOL(1) | TKCHS((TS_CH[TS_Index+i])+1); 
	}
	TKCON |= TKST(1);	
}
unsigned char TS_GetDataArea(unsigned char ts_ch,unsigned int ts_data,int NoiseThd,bit key_pressed_flag)
{
	int Delta;
	int FingerThd;
	
	Delta 		= (int)TS_BaseLineData[ts_ch] - (int)ts_data;
	FingerThd = TSKey_FingerThd[ts_ch];		
	
	if(key_pressed_flag)
	{
		FingerThd = (FingerThd*90)/100;	
	}
	
	if(Delta >= FingerThd)			return AREA_FINGER_TOUCH; 
	else if(Delta > NoiseThd)		return AREA_PNOISE_PLUS; 
	else if(Delta >= 0)					return AREA_PNOISE;
	else if(Delta >= -NoiseThd) return AREA_NNOISE;
	else 												return AREA_OVER_LOW;
}
unsigned char TS_AreaDeviateDetection(unsigned int cmp_data,unsigned int real_data,int range)
{	
	int Delta;
	Delta 	= (int)cmp_data - (int)real_data;
	if((Delta <= range) && (Delta >= -range))
	{
		return 1;
	}
	else
	{
		return 0;	
	}		
}
void TS_BaseLineForceUpdate(void)
{
	unsigned char i;

	for(i = 0; i < TS_Cnt; i++)
	{
		TS_FirstAreaData[i] = TS_PostData[i];
		TS_BaseLineData[i] 	= TS_PostData[i];
		TS_AreaConfirmTimerSet(i,AREA_PNOISE);						
	}	
}

void TS_AreaConfirmTimerSet(unsigned char ts_ch, unsigned char area)
{
	TS_AreaConfirmTimer[ts_ch] = AREA_CONFIRM_TIME_TAB[area];
}
void SetWheelSliderRefCh(unsigned char SliderNum,unsigned char Key_Cnt)
{
	unsigned char num,i,j;
	unsigned int MinVal;
	TS_BaseCh = Key_Cnt; 
	for(num = 0; num < SliderNum; num++)
	{
		MinVal = 0xFFFF;
		for(i = TS_BaseCh,j=0; i < TS_BaseCh + SLIDER_CH_COUNT[num]; i++,j++)
		{
			if(TS_BaseLineData[i] < MinVal)
			{
				WheelSliderRefCh[num] = j;
				MinVal = TS_BaseLineData[i];
			}
		}
		TS_BaseCh += SLIDER_CH_COUNT[num];
	}	
}
#define WHEEL_SLIDER_POSITION_FILTER_COUNT				4			
int WheelSliderTouchJudge(unsigned char num)
{
	unsigned char i;
	unsigned long int CalcTemp1;
	unsigned int CalcTemp2,CalcTemp3;
	unsigned char DeltaRate;
	int  Delta;
	unsigned int  MaxDelta1,MaxDelta2/*,MaxDelta3*/;
	unsigned char Maxidx1,Maxidx2/*,Maxidx3*/;
	int Position,PosOffset;
	unsigned char	*pMinRate;
	
	pMinRate = WHEEL_SLIDER_MIN_RATE[num];
	MaxDelta1 = MaxDelta2 = /*MaxDelta3 =*/ 0;

	for(i = 0; i < SLIDER_CH_COUNT[num]; i++)	
	{	
		if(i == WheelSliderRefCh[num]) 	
		{
			Delta			= 	(int)TS_BaseLineData[TS_BaseCh + WheelSliderRefCh[num]] - (int)TS_PostData[TS_BaseCh + WheelSliderRefCh[num]];	
		}
		else
		{
			CalcTemp1 = 	(unsigned long int)TS_PostData[TS_BaseCh + i] * (unsigned long int)TS_BaseLineData[TS_BaseCh + WheelSliderRefCh[num]];
			CalcTemp2 =  	(unsigned int)(CalcTemp1/TS_BaseLineData[TS_BaseCh + i]);
			CalcTemp3 = 	TS_PostData[TS_BaseCh + i] + TS_BaseLineData[TS_BaseCh + WheelSliderRefCh[num]] - CalcTemp2;
			CalcTemp2 = 	(unsigned int)(CalcTemp1/CalcTemp3);	
			Delta 		= 	(int)TS_BaseLineData[TS_BaseCh + WheelSliderRefCh[num]] - (int)CalcTemp2;					
		}
		if(Delta < 0) Delta = 0;
	
		
		if(Delta > MaxDelta1)
		{
// 			Maxidx3 = Maxidx2;	MaxDelta3 = MaxDelta2;
			Maxidx2 = Maxidx1;	MaxDelta2 = MaxDelta1;
			Maxidx1 = i;				MaxDelta1 = Delta;
		}
		else if(Delta > MaxDelta2)
		{
// 			Maxidx3 = Maxidx2;	MaxDelta3 = MaxDelta2;
			Maxidx2 = i;				MaxDelta2 = Delta;
		}
// 		else if(Delta > MaxDelta3)
// 		{
// 			Maxidx3 = i;				MaxDelta3 = Delta;
// 		}
	}
	if((WHEEL_OR_SLIDER_DEF[num] == SLIDER)&&((Maxidx1 == 0)||(Maxidx1 == (SLIDER_CH_COUNT[num]-1))))
	{
		if((MaxDelta1) < (WHEEL_SLIDER_TOUCH_THD[num]>>1))
		{
			return -1;
		}
	}
	else
	{
		if((MaxDelta1 + MaxDelta2) < WHEEL_SLIDER_TOUCH_THD[num])
		{
			return -1;
		}		
	}

	Delta = MaxDelta1 - (WHEEL_SLIDER_TOUCH_THD[num]>>1);
	DeltaRate = (Delta*10)/MaxDelta1;
	if(DeltaRate > 31) DeltaRate = 31;
	
	CalcTemp2 = ((unsigned int)WHEEL_SLIDER_TOUCH_THD[num]*(32-DeltaRate))>>6;
	
	MaxDelta1 += CalcTemp2;
	MaxDelta2 += CalcTemp2;		

	DeltaRate = ((unsigned int)MaxDelta2<<7)/MaxDelta1;
	if(WheelSliderCapRateFilter[num] == 0)
	{
		WheelSliderCapRateFilter[num] = DeltaRate*WHEEL_SLIDER_POSITION_FILTER_COUNT;
	}
	else
	{
		WheelSliderCapRateFilter[num] -= WheelSliderCapRateFilter[num]/WHEEL_SLIDER_POSITION_FILTER_COUNT;
		WheelSliderCapRateFilter[num] += DeltaRate;	
	}
	DeltaRate = WheelSliderCapRateFilter[num]/WHEEL_SLIDER_POSITION_FILTER_COUNT;
	WheelSliderMaxIdx[num] = Maxidx1;
	

	if(WHEEL_OR_SLIDER_DEF[num] == SLIDER)
	{
		Position = Maxidx1*64;
		if(Maxidx1 == 0)
		{
			if(DeltaRate < pMinRate[0])
			{
				DeltaRate = pMinRate[0];
			}
			Position = ((DeltaRate - pMinRate[0])*32)/(128-pMinRate[0]);
		}
		else if(Maxidx1 == (SLIDER_CH_COUNT[num]-1))
		{
			if(DeltaRate < pMinRate[SLIDER_CH_COUNT[num]-1])
			{
				DeltaRate = pMinRate[SLIDER_CH_COUNT[num]-1];
			}
			Position -= ((DeltaRate - pMinRate[SLIDER_CH_COUNT[num]-1])*32)/(128-pMinRate[SLIDER_CH_COUNT[num]-1]);
		}
		else
		{
			if(DeltaRate < pMinRate[Maxidx1]) DeltaRate = pMinRate[Maxidx1];
			PosOffset = ((DeltaRate - pMinRate[Maxidx1])*32)/(128-pMinRate[Maxidx1]);
			if(Maxidx1 < Maxidx2)
			{
				Position += PosOffset;
			}
			else
			{
				Position -= PosOffset;
			}
		}

	}
	else if(WHEEL_OR_SLIDER_DEF[num] == WHEEL)
	{
		bit dir_flag;
		Position = Maxidx1*64;
		if(DeltaRate < pMinRate[Maxidx1]) DeltaRate = pMinRate[Maxidx1];
		PosOffset = ((DeltaRate - pMinRate[Maxidx1])*32)/(128-pMinRate[Maxidx1]);
		
		if((Maxidx1 == 0) && (Maxidx2 == (SLIDER_CH_COUNT[num]-1))) dir_flag = 0;
		else if((Maxidx1 == (SLIDER_CH_COUNT[num]-1)) && (Maxidx2 == 0)) dir_flag = 1;
		else if(Maxidx1 < Maxidx2) dir_flag = 1;
		else dir_flag = 0;
		
		if(dir_flag)
		{
			Position += PosOffset;
		}
		else
		{
			if(Position == 0)
			{
				Position = SLIDER_CH_COUNT[num]*64-1;
			}
			Position -= PosOffset;
		}

	}
	return Position;
}
#endif
